#-*- coding:utf-8 -*-
#!/usr/bin/env python
import time, datetime, _thread as thread
import sys
import os
from socket import *
from struct import *
import logging

def getLogger():
	logger = logging.getLogger('gg')

	dirpath = './log'
	#dirpath = 'd:\log'
	filename = 'reply_%s.log' % time.strftime("%Y%m%d", time.localtime())
	handler = logging.FileHandler(os.path.join(dirpath, filename))

	formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s')

	logger.addHandler(handler)
	logger.setLevel(logging.INFO)

	return logger

log = getLogger()


class replyData():
	ringBuffer = []
	sockFD = 0
	log = 0
	returnBuffer = []
	res = []
	functionCode = {}

	def __init__(self):
		pass

	def reply(self, data, sock_fd):
		sockFD = sock_fd
		strFromat = "!%dB" % len(data)
		self.ringBuffer.extend(list(unpack(strFromat, data)))
		self.parse()
		self.res = self.returnBuffer
		self.returnBuffer = []
		return self.res

	def parse(self):
		try:
			while True:
				#print(self.ringBuffer)
				if len(self.ringBuffer) < 10:
					break
				if self.ringBuffer[0] != 0xaa:
					del self.ringBuffer[0]
					continue
				if self.ringBuffer[0] == 0xaa:
					if (self.ringBuffer[1] == 0xaa) and (len(self.ringBuffer) <= 11):
						break
					elif (self.ringBuffer[1] == 0xaa) and (len(self.ringBuffer) > 11):
						#print(len(self.ringBuffer))
						self.getFrame()
						continue
					else:
						del self.ringBuffer[0]
						continue
		except Exception as err:
			print(err)
			pass

	def xor(self, data):
		res = 0x00
		for atom in data:
			res = res ^ atom
		return res
		
	def send(self, frameData):
		data = [0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00] 

		data[3] = frameData[3]
		data[4] = frameData[4]
		data[5] = frameData[5]
		data[6] = frameData[6]
		data[9] = frameData[9]
		
		data[8] = self.xor(data)

		try:
			sendBuffer = pack("!10B", *data)
		except Exception as err:
			strTmp = "[%s][%-10s:line %4d] %s" % (time.strftime('%Y-%m-%d %H:%M:%S'), sys._getframe().f_code.co_name, sys._getframe().f_lineno, err)
			self.log.info(strTmp)
		
		try:
			self.returnBuffer.append(sendBuffer)
		except Exception as err:
			#print('[', sys._getframe().f_code.co_name, ':', sys._getframe().f_lineno, ']', err)
			strTmp = "[%s][%-10s:line %4d] %s" % (time.strftime('%Y-%m-%d %H:%M:%S'), sys._getframe().f_code.co_name, sys._getframe().f_lineno, err)
			self.log.info(strTmp)
			
		return

	def login(self, frameData):
		data = frameData

		data[0] = 0xab
		data[1] = 0xab
		data[7] = 0x01
		data[8] = 0x00
		del data[10:14]
		data[8] = self.xor(data)

		sendBuffer = pack("!10B", *data)
		print(sendBuffer)
		
		try:
			self.returnBuffer.append(sendBuffer)
		except Exception as err:
			#print('[', sys._getframe().f_code.co_name, ':', sys._getframe().f_lineno, ']', err)
			strTmp = "[%s][%-10s:line %4d] %s" % (time.strftime('%Y-%m-%d %H:%M:%S'), sys._getframe().f_code.co_name, sys._getframe().f_lineno, err)
			self.log.info(strTmp)
			
		return
			
	def timing(self, frameData):
		data = frameData

		localTime = datetime.datetime.now()

		data[0] = 0xab
		data[1] = 0xab
		data[7] = 0x07
		data[8] = 0x00
		del data[10]
		
		data.append(localTime.year - 2000)
		data.append(localTime.month)
		data.append(localTime.day)
		data.append(localTime.hour)
		data.append(localTime.minute)
		data.append(localTime.second)

		data[8] = self.xor(data)

		"""
		for atom in frameData:
			print("%02x" % atom, end=' ')
		print('')
		"""

		sendBuffer = pack("!16B", *data)

		try:
			self.returnBuffer.append(sendBuffer)
		except Exception as err:
			#print('[', sys._getframe().f_code.co_name, ':', sys._getframe().f_lineno, ']', err)
			strTmp = "[%s][%-10s:line %4d] %s" % (time.strftime('%Y-%m-%d %H:%M:%S'), sys._getframe().f_code.co_name, sys._getframe().f_lineno, err)
			self.log.info(strTmp)
		return


	def getFrame(self):
		#print(len(self.ringBuffer), self.ringBuffer[7] + 9)
		if len(self.ringBuffer) < self.ringBuffer[7] + 9:
			del self.ringBuffer[0]
			return
		frameData = self.ringBuffer[0:self.ringBuffer[7] + 9]
		del self.ringBuffer[0:self.ringBuffer[7] + 9]
		#print(frameData, self.ringBuffer)
		
####################################################################
##		Get one frame data from the ringBuffer
####################################################################
		
		
		if self.xor(frameData) != 0:
			return
		
		##	function code: 0x10		login request
		if frameData[5] == 0x10:
			self.login(frameData)
		
		##	function code: 0x11		timing
		elif frameData[5] == 0x11:
			self.timing(frameData)
			
		##	function code: 0x12		heart
		elif frameData[5] == 0x12:
			self.send(frameData)
			
		##	function code: 0x30		single vehicle
		elif frameData[5] == 0x30:
			self.send(frameData)
		
		elif frameData[5] == 0x35:
			print("%s  " % now(), end='')
			for atom in frameData:
				print("%02x" % atom, end=' ')
			print('')

			self.send(frameData)
		
		elif frameData[5] == 0x36:
			self.send(frameData)

		elif frameData[5] == 0x81:
			pass
		
		else:
			self.send(frameData)

def now():
	return time.ctime(time.time())

